package com.tsfyun.scm.controller.customs;


import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.annotation.DuplicateSubmit;
import com.tsfyun.common.base.dto.Result;
import com.tsfyun.common.base.dto.TaskDTO;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.validator.group.UpdateGroup;
import com.tsfyun.scm.dto.customs.ConfirmDeclarationDTO;
import com.tsfyun.scm.dto.customs.DeclarationQTO;
import com.tsfyun.scm.entity.customs.Declaration;
import com.tsfyun.scm.service.customs.IDeclarationService;
import com.tsfyun.scm.vo.customs.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.tsfyun.common.base.controller.BaseController;
import org.springframework.web.multipart.MultipartFile;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 报关单 前端控制器
 * </p>
 *
 *
 * @since 2020-04-24
 */
@Slf4j
@RestController
@RequestMapping("/declaration")
public class DeclarationController extends BaseController {

    @Autowired
    private IDeclarationService declarationService;

    /**
     * 进口报关单分页查询（带客户权限判断）
     * @param qto
     * @return
     */
    @PostMapping(value = "list")
    public Result<List<DeclarationListVO>> pageList(@ModelAttribute DeclarationQTO qto) {
        PageInfo<DeclarationListVO> page = declarationService.pageList(qto);
        return success((int)page.getTotal(),page.getList());
    }

    /**=
     * 根据选择的ID查询单据
     * @param ids
     * @return
     */
    @PostMapping(value = "idsList")
    public Result<List<DeclarationListVO>> idsList(@RequestParam(value = "ids")String ids){
        return success(declarationService.waitSendList(Arrays.asList(ids.split(","))));
    }

    /**=
     * 发送单一窗口
     * @param id
     * @return
     */
    @PostMapping(value = "sendSinglewindow")
    public Result<Void> sendSinglewindow(@RequestParam(value = "id")Long id){
        declarationService.importSinglewindow(id);
        return success();
    }

    /**
     * 复核确认
     * @param dto
     * @return
     */
    @DuplicateSubmit
    @PostMapping(value = "confirm")
    public Result<Void> confirm(@ModelAttribute @Validated(UpdateGroup.class) ConfirmDeclarationDTO dto) {
        declarationService.confirm(dto);
        return success();
    }

    /**
     * 退回验货
     * @param id
     * @param info
     * @return
     */
    @DuplicateSubmit
    @PostMapping(value = "backInspection")
    public Result<Void> backInspection(@RequestParam(value = "id")Long id,@RequestParam(value = "info",required = false,defaultValue = "")String info){
        declarationService.backInspection(id,info);
        return success();
    }


    /**
     * 报关单详情信息（可以兼容操作页面获取数据并进行状态验证）
     * @param id
     * @return
     */
    @PostMapping(value = "detail")
    public Result<DeclarationPlusDetailVO> detail(@RequestParam("id")Long id,@RequestParam(value = "operation",required = false)String operation) {
        return success(declarationService.detail(id,operation));
    }

    /**=
     * 报关单主单详情
     * @param id
     * @return
     */
    @PostMapping(value = "mainDetail")
    public Result<DeclarationVO> mainDetail(@RequestParam("id")Long id,@RequestParam(value = "operation",required = false)String operation) {
        return success(declarationService.mainDetail(id,operation));
    }

    /**=
     * 报关单明细详情
     * @param id
     * @return
     */
    @PostMapping(value = "memberDetail")
    public Result<List<DeclarationMemberVO>> memberDetail(@RequestParam("id")Long id) {
        return success(declarationService.memberDetail(id));
    }

    /**
     * 确认申报
     * @param dto
     * @return
     */
    @DuplicateSubmit
    @PostMapping(value = "confirmDeclare")
    public Result<Void> confirmDeclare(@ModelAttribute @Validated() TaskDTO dto) {
        declarationService.confirmDeclare(dto);
        return success();
    }

    /**=
     * 申报完成
     * @param dto
     * @return
     */
    @DuplicateSubmit
    @PostMapping(value = "declarationCompleted")
    public Result<Void> declarationCompleted(@ModelAttribute @Validated() TaskDTO dto){
        declarationService.declarationCompleted(dto);
        return success();
    }

    /**=
     * 获取合同数据
     * @param id
     * @return
     */
    @PostMapping(value = "contractData")
    public Result<ContractPlusVO> contractData(@RequestParam(value = "id")Long id){
        return success(declarationService.contractData(id));
    }

    /**=
     * 舱单申请发送单一窗口
     * @param id
     * @return
     */
    @PostMapping(value = "generateSendManifest")
    public Result<Void> generateSendManifest(@RequestParam(value = "id")Long id){
        declarationService.generateManifest(id);
        return success();
    }

    /**=
     * 舱单删除申请发送单一窗口
     * @param id
     * @return
     */
    @PostMapping(value = "removeManifest")
    public Result<Void> removeManifest(@RequestParam(value = "id")Long id){
        declarationService.removeManifest(id);
        return success();
    }

    /**
     * 发送至报关行
     * @param id
     * @return
     */
    @DuplicateSubmit
    @PostMapping(value = "sendToScmbot")
    public Result<Void> sendToScmbot(@RequestParam(value = "id")Long id) {
        declarationService.sendToScmbot(id);
        return success();
    }

    /**
     * 导入报关单号
     * @param file
     * @return
     */
    @PostMapping(value = "importData")
    public Result importData(@RequestPart(value = "file") MultipartFile file){
        declarationService.importExcel(file);
        return Result.success();
    }

    /**
     * 发送至报关行
     * @param id
     * @return
     */
    @DuplicateSubmit
    @PostMapping(value = "sendToScmbotApi")
    public Result<Void> sendToScmbotApi(@RequestParam(value = "id")Long id) {
        declarationService.sendToScmbotDeclare(id);
        return success();
    }

    /**
     * 导出报关单草单
     * @param id
     */
    @GetMapping(value = "exportDraft")
    public void exportDraft(@RequestParam(value = "id")Long id,@RequestParam(value = "notShowFields",required = false)String notShowFields){
        HSSFWorkbook workbook;
        OutputStream outputStream = null;
        try {
            Map<String,Object> dataMap = declarationService.exportDraft(id, StringUtils.isNotEmpty(notShowFields) ? Arrays.asList(notShowFields.split(",")) : Lists.newArrayList());
            workbook = (HSSFWorkbook)dataMap.get("workbook");
            Declaration declaration = (Declaration) dataMap.get("declaration");
            String contentType = "application/ms-excel;charset=UTF-8";
            response.setHeader("Content-disposition","attachment;filename=" + URLEncoder.encode(StrUtil.format("报关单草单{}",declaration.getDocNo()) + ".xls", "UTF-8"));
            response.setContentType(contentType);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (Exception e) {
            log.error("导出异常",e);
        } finally {
            if(Objects.nonNull(outputStream)) {
                IOUtils.closeQuietly(outputStream);
            }
        }
    }

    /**=
     * 获取境外合同数据
     * @param id
     * @return
     */
    @PostMapping(value = "overseasContractData")
    public Result<ContractPlusVO> overseasContractData(@RequestParam(value = "id")Long id){
        return success(declarationService.overseasContractData(id));
    }


    /**=
     * 申报完成 回调
     * @param docNo
     * @return
     */
    @PostMapping(value = "decCompletedCallBack")
    public Result<Void> declarationCompletedCallBack(@RequestParam(value = "docNo")String docNo){
        declarationService.declarationCompletedCallBack(docNo);
        return success();
    }

}

